home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programmer Power Tools
/
Programmer Power Tools.iso
/
progjrn
/
pj_5_3.arc
/
PJ3.ASM
Wrap
Assembly Source File
|
1987-10-12
|
5KB
|
222 lines
; Program to illustrate operation of data rotate and bit mask
; features of Graphics Data Controller. Draws 8x8 character at
; specified location, using EGA's 8x8 ROM font. Designed
; for use with modes 0Dh, 0Eh, 0Fh, and 10h.
; Assembled with MASM 4.0, linked with LINK 3.51.
; Copyright by Michael Abrash, 2/8/87.
;
stack segment para stack 'STACK'
db 512 dup(?)
stack ends
;
EGA_VIDEO_SEGMENT equ 0a000h ;EGA display memory segment
SCREEN_WIDTH_IN_BYTES equ 044ah ;offset of BIOS variable
FONT_CHARACTER_SIZE equ 8 ;# bytes in each font char
;
; EGA register equates.
;
GDC_INDEX equ 3ceh ;GDC index register
GDC_ROTATE equ 3 ;GDC data rotate/logical function
; register index
GDC_BIT_MASK equ 8 ;GDC bit mask register index
;
dseg segment para common 'DATA'
TEST_TEXT_ROW equ 69 ;row to display test text at
TEST_TEXT_COL equ 17 ;column to display test text at
TEST_TEXT_WIDTH equ 8 ;width of a character in pixels
TestString label byte
db 'Hello, world!',0 ;test string to print.
FontPointer dd ? ;font offset
dseg ends
;
; Macro to set indexed register INDEX of GDC chip to SETTING.
;
SETGDC macro INDEX, SETTING
mov dx,GDC_INDEX
mov ax,(SETTING SHL 8) OR INDEX
out dx,ax
endm
;
cseg segment para public 'CODE'
assume cs:cseg, ds:dseg
start proc near
mov ax,dseg
mov ds,ax
;
; Select 640x350 graphics mode.
;
mov ax,010h
int 10h
;
; Set driver to use the 8x8 font.
;
mov ah,11h ;EGA BIOS character generator function,
mov al,30h ; return info subfunction
mov bh,3 ;get 8x8 font pointer
int 10h
call SelectFont
;
; Print the test string.
;
mov si,offset TestString
mov bx,TEST_TEXT_ROW
mov cx,TEST_TEXT_COL
StringOutLoop:
lodsb
and al,al
jz StringOutDone
call DrawChar
add cx,TEST_TEXT_WIDTH
jmp StringOutLoop
StringOutDone:
;
; Reset the data rotate and bit mask registers.
;
SETGDC GDC_ROTATE, 0
SETGDC GDC_BIT_MASK, 0ffh
;
; Exit to DOS.
;
mov ah,4ch
int 21h
Start endp
;
; Subroutine to draw a text character in a linear graphics mode
; (0Dh, 0Eh, 0Fh, 010h).
; Font used should be pointed to by FontPointer.
;
; Input:
; AL = character to draw
; BX = row to draw text character at
; CX = column to draw text character at
;
; Forces ALU function to "move".
;
DrawChar proc near
push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
;
; Set DS:SI to point to font and ES to point to display memory.
;
lds si,[FontPointer] ;point to font
mov dx,EGA_VIDEO_SEGMENT
mov es,dx ;point to display memory
;
; Calculate screen address of byte character starts in.
;
push ds ;point to BIOS data segment
sub dx,dx
mov ds,dx
xchg ax,bx
mov di,ds:[SCREEN_WIDTH_IN_BYTES] ;retrieve BIOS
; screen width
pop ds
mul di ;calculate offset of start of row
push di ;set aside screen width
mov di,cx ;set aside the column
and cl,0111b ;keep only the column in-byte address
shr di,1
shr di,1
shr di,1 ;divide column by 8 to make a byte address
add di,ax ;and point to byte
;
; Calculate font address of character.
;
sub bh,bh
shl bx,1 ;assumes 8 bytes per character; use
shl bx,1 ; a multiply otherwise
shl bx,1 ;offset in font of character
add si,bx ;offset in font segment of character
;
; Set up the GDC rotation.
;
mov dx,GDC_INDEX
mov al,GDC_ROTATE
mov ah,cl
out dx,ax
;
; Set up BH as bit mask for left half,
; BL as rotation for right half.
;
mov bx,0ffffh
shr bh,cl
neg cl
add cl,8
shl bl,cl
;
; Draw the character, left half first, then right half in the
; succeeding byte, using the data rotation to position the character
; across the byte boundary and then using the bit mask to get the
; proper portion of the character into each byte.
; Does not check for case where character is byte-aligned and
; no rotation and only one write is required.
;
mov bp,FONT_CHARACTER_SIZE
mov dx,GDC_INDEX
pop cx ;get back screen width
dec cx
dec cx ; -2 because do two bytes for each char
CharacterLoop:
;
; Set the bit mask for the left half of the character.
;
mov al,GDC_BIT_MASK
mov ah,bh
out dx,ax
;
; Get the next character byte & write it to display memory.
; (Left half of character.)
;
mov al,[si] ;get character byte
mov ah,es:[di] ;load latches
stosb ;write character byte
;
; Set the bit mask for the right half of the character.
;
mov al,GDC_BIT_MASK
mov ah,bl
out dx,ax
;
; Get the character byte again & write it to display memory.
; (Right half of character.)
;
lodsb ;get character byte
mov ah,es:[di] ;load latches
stosb ;write character byte
;
; Point to next line of character in display memory.
;
add di,cx
;
dec bp
jnz CharacterLoop
;
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
DrawChar endp
;
; Set the pointer to the font to draw from to ES:BP.
;
SelectFont proc near
mov word ptr [FontPointer],bp ;save pointer
mov word ptr [FontPointer+2],es
ret
SelectFont endp
;
cseg ends
end start